package com.chagee.store.operation.server.service.biz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chagee.base.utils.PaginationData;
import com.chagee.base.utils.PaginationRequest;
import com.chagee.personnel.api.event.bo.PersonnelInfo;
import com.chagee.store.operation.api.bo.CommentExtDataBO;
import com.chagee.store.operation.api.enums.CommentTypeEnum;
import com.chagee.store.operation.api.enums.EnableFlagEnum;
import com.chagee.store.operation.common.exception.BizErrorCode;
import com.chagee.store.operation.common.exception.BizException;
import com.chagee.store.operation.common.utils.ResponseUtil;
import com.chagee.store.operation.server.entity.CommentConfigurationDO;
import com.chagee.store.operation.server.entity.OperateRecordDO;
import com.chagee.store.operation.server.entity.StoreDO;
import com.chagee.store.operation.server.entity.StoreDetailDO;
import com.chagee.store.operation.server.entity.StoreOrderEvaluateDO;
import com.chagee.store.operation.server.event.service.CommentConfigurationBaseService;
import com.chagee.store.operation.server.event.service.OperateRecordBaseService;
import com.chagee.store.operation.server.generator.codeGenerator.CommentNoCodeGenerator;
import com.chagee.store.operation.server.model.bo.CommentConfigurationBO;
import com.chagee.store.operation.server.model.param.AddCommentConfigParam;
import com.chagee.store.operation.server.model.param.CommentConfigurationParam;
import com.chagee.store.operation.server.model.param.CommentDetailParam;
import com.chagee.store.operation.server.model.param.EnableCommentParam;
import com.chagee.store.operation.server.model.param.QueryOperateRecordParam;
import com.chagee.store.operation.server.model.param.UpdateCommentConfigParam;
import com.chagee.store.operation.server.model.vo.CommentConfigurationVO;
import com.chagee.store.operation.server.model.vo.OperateRecordVo;
import com.chagee.store.operation.server.service.PersonnelThirdService;
import com.chagee.store.operation.server.transfer.ChangeInfoTransfer;
import com.chagee.storeManagement.api.event.enums.OptResourceEnum;
import com.chagee.storeManagement.api.event.param.StoreExt;
import com.chagee.storeManagement.api.event.response.QueryStoreOperateRecordResponse;
import com.personnel.auth.service.PersonnelAuthService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author : hk
 * @Date : 2024/7/5
 */

@Slf4j
@Service
public class CommentConfigurationBizService {

	@Resource
	private CommentConfigurationBaseService commentConfigurationBaseService;

	@Resource
	private PersonnelThirdService personnelThirdService;

	@Resource
	private CommentNoCodeGenerator commentNoCodeGenerator;

	@Resource
	private OperateRecordBaseService operateRecordBaseService;

	public PaginationData<CommentConfigurationVO> queryCommentConfigPage(PaginationRequest<CommentConfigurationParam> request) {
		Page<CommentConfigurationDO> page = new Page<>(request.getPageNum(), request.getPageSize());
		Page<CommentConfigurationDO> taskRelationDOPage = commentConfigurationBaseService.pageQueryList(request.getQueryParameter(), page);
		if (CollectionUtils.isEmpty(taskRelationDOPage.getRecords())) {
			return ResponseUtil.emptyResponse(request, CommentConfigurationVO.class, taskRelationDOPage.getTotal());
		}
		List<CommentConfigurationVO> result = taskRelationDOPage.getRecords().stream().map(s -> {
			CommentConfigurationVO info = new CommentConfigurationVO();
			BeanUtils.copyProperties(s, info);
			//单选 ;多选
			if (s.getCommentType().equals(CommentTypeEnum.SINGLE_CHOICE.getType()) || s.getCommentType().equals(CommentTypeEnum.MULTIPLE_CHOICE.getType())){
				List<CommentExtDataBO> extDataBOS = JSONArray.parseArray(s.getExtData(), CommentExtDataBO.class);
				info.setExtData(extDataBOS);
			}
			return info;
		}).collect(Collectors.toList());
		return ResponseUtil.commonResponse(request, result, taskRelationDOPage.getTotal());
	}

	@Transactional(rollbackFor = Exception.class)
	public Boolean addComment(AddCommentConfigParam request) {
		CommentTypeEnum commentTypeEnum = CommentTypeEnum.queryByType(request.getCommentType());
		if (Objects.isNull(commentTypeEnum)) {
			throw new BizException(BizErrorCode.COMMENT_IS_NULL);
		}
		if (commentTypeEnum.name().equals(CommentTypeEnum.SINGLE_CHOICE.name()) && Objects.isNull(request.getExtData())) {
			throw new BizException(BizErrorCode.COMMENT_QUESTION_IS_NULL);
		}
		PersonnelInfo loginUser = personnelThirdService.getLoginUserInfoInWeb();
		log.info("CommentConfigurationBizService#getLoginUserInfoInWeb:{}", JSON.toJSONString(loginUser));
		CommentConfigurationDO configurationDO = new CommentConfigurationDO();
		configurationDO.setCommentCode(commentNoCodeGenerator.generate());
		configurationDO.setCommentName(request.getCommentName());
		configurationDO.setCommentQuestion(request.getCommentQuestion());
		configurationDO.setCommentType(commentTypeEnum.getType());
		configurationDO.setExtData(JSONObject.toJSONString(request.getExtData()));
		configurationDO.setSort(request.getSort());
		configurationDO.setEnableFlag(request.getEnableFlag());

		if (!Objects.isNull(loginUser) && StringUtils.isNotBlank(loginUser.getRealName())){
			configurationDO.setUserName(loginUser.getRealName());
		}
		if (!Objects.isNull(loginUser) && ObjectUtils.isNotEmpty(loginUser.getId())){
			configurationDO.setCreateUser(String.valueOf(loginUser.getId()));
		}
		if (!Objects.isNull(loginUser) && StringUtils.isNotBlank(loginUser.getDeptId())){
			configurationDO.setCreateDept(loginUser.getDeptId().split(",")[0]);
		}
		boolean result = commentConfigurationBaseService.save(configurationDO);
		if (result){
			//增加更新操作记录
			OperateRecordDO operateRecordDO = new OperateRecordDO();
			operateRecordDO.setStoreNo("");
			operateRecordDO.setUpdateBefore("");
			operateRecordDO.setUpdateData(request.getCommentName());
			if (!Objects.isNull(loginUser) && StringUtils.isNotBlank(loginUser.getRealName())){
				operateRecordDO.setUpdateFrom(loginUser.getRealName());
			}else {
				operateRecordDO.setUpdateFrom("");
			}
			if (!Objects.isNull(loginUser) && StringUtils.isNotBlank(loginUser.getDeptId())){
				operateRecordDO.setCreateDept(loginUser.getDeptId().split(",")[0]);
			}
			if (!Objects.isNull(loginUser) && ObjectUtils.isNotEmpty(loginUser.getId())){
				operateRecordDO.setCreateUser(String.valueOf(loginUser.getId()));
			}
			if (!Objects.isNull(loginUser) && ObjectUtils.isNotEmpty(loginUser.getFeishuEmpNo())){
				operateRecordDO.setUpdateFromCode(String.valueOf(loginUser.getFeishuEmpNo()));
			}
			operateRecordBaseService.addInsertOptRecord(operateRecordDO);
		}

		return result;
	}

	public CommentConfigurationVO commentDetail(CommentDetailParam request) {
		CommentConfigurationDO configurationDO = commentConfigurationBaseService.getById(request.getId());
		CommentConfigurationVO configurationVO = new CommentConfigurationVO();
		BeanUtils.copyProperties(configurationDO, configurationVO);
		//单选 ;多选
		if (configurationDO.getCommentType().equals(CommentTypeEnum.SINGLE_CHOICE.getType()) || configurationDO.getCommentType().equals(CommentTypeEnum.MULTIPLE_CHOICE.getType())){
			List<CommentExtDataBO> extDataBOS = JSONArray.parseArray(configurationDO.getExtData(), CommentExtDataBO.class);
			configurationVO.setExtData(extDataBOS);
		}
		return configurationVO;
	}

	@Transactional(rollbackFor = Exception.class)
	public Boolean updateComment(UpdateCommentConfigParam request) {
		CommentTypeEnum commentTypeEnum = CommentTypeEnum.queryByType(request.getCommentType());
		if (Objects.isNull(commentTypeEnum)) {
			throw new BizException(BizErrorCode.COMMENT_IS_NULL);
		}
		//单选,多选
		if ((commentTypeEnum.name().equals(CommentTypeEnum.SINGLE_CHOICE.name()) || commentTypeEnum.name().equals(CommentTypeEnum.MULTIPLE_CHOICE.name())) && Objects.isNull(request.getExtData())) {
			throw new BizException(BizErrorCode.COMMENT_QUESTION_IS_NULL);
		}
		PersonnelInfo loginUser = personnelThirdService.getLoginUserInfoInWeb();
		log.info("CommentConfigurationBizService#getLoginUserInfoInWeb:{}",JSON.toJSONString(loginUser));

		OperateRecordDO operateRecordDO = new OperateRecordDO();
		CommentConfigurationDO commentConfigurationDO = commentConfigurationBaseService.getById(request.getId());
		if (Objects.isNull(commentConfigurationDO)){
			throw new BizException(BizErrorCode.NOT_GTE_COMMENT_INFO);
		}
		CommentConfigurationDO configurationDO = new CommentConfigurationDO();
		configurationDO.setId(commentConfigurationDO.getId());
		if (StringUtils.isNotBlank(request.getCommentName())){
			configurationDO.setCommentName(request.getCommentName());
		}
		if (StringUtils.isNotBlank(request.getCommentQuestion())){
			configurationDO.setCommentQuestion(request.getCommentQuestion());
		}
		if (StringUtils.isNotBlank(commentTypeEnum.getType())){
			configurationDO.setCommentType(commentTypeEnum.getType());
		}
		if (CollectionUtils.isNotEmpty(request.getExtData())){
			configurationDO.setExtData(JSONObject.toJSONString(request.getExtData()));
		}
		if (!Objects.isNull(request.getSort())){
			configurationDO.setSort(request.getSort());
		}
		if (!Objects.isNull(request.getEnableFlag())){
			configurationDO.setEnableFlag(request.getEnableFlag());
		}
		Pair<String, String> changeInfo = beanChangeInfo(commentConfigurationDO, configurationDO);
		boolean result = commentConfigurationBaseService.updateById(configurationDO);
		if (result){
			//修改更新操作记录
			operateRecordDO.setStoreNo("");
			operateRecordDO.setUpdateBefore(changeInfo.getLeft());
			operateRecordDO.setUpdateData(changeInfo.getRight());
			if (!Objects.isNull(loginUser) && StringUtils.isNotBlank(loginUser.getRealName())){
				operateRecordDO.setUpdateFrom(loginUser.getRealName());
			}else {
				operateRecordDO.setUpdateFrom("");
			}
			if (!Objects.isNull(loginUser) && StringUtils.isNotBlank(loginUser.getDeptId())){
				operateRecordDO.setCreateDept(loginUser.getDeptId().split(",")[0]);
			}
			if (!Objects.isNull(loginUser) && ObjectUtils.isNotEmpty(loginUser.getId())){
				operateRecordDO.setCreateUser(String.valueOf(loginUser.getId()));
			}
			if (!Objects.isNull(loginUser) && ObjectUtils.isNotEmpty(loginUser.getFeishuEmpNo())){
				operateRecordDO.setUpdateFromCode(String.valueOf(loginUser.getFeishuEmpNo()));
			}
			operateRecordBaseService.addUpdateOptRecord(operateRecordDO);
		}
		return result;
	}
	/**
	 * 变更记录
	 * @param ov ov
	 * @param nv nv
	 * @return info
	 */
	private Pair<String, String> beanChangeInfo(CommentConfigurationDO ov, CommentConfigurationDO nv) {
		CommentConfigurationBO oldData = new CommentConfigurationBO();
		CommentConfigurationBO newData = new CommentConfigurationBO();
		BeanUtils.copyProperties(ov, oldData);
		BeanUtils.copyProperties(nv, newData);
		Pair<String, String> changeInfo = ChangeInfoTransfer.getChangeInfo(oldData, newData);
		StringBuilder pairLeft = new StringBuilder();
		StringBuilder pairRight = new StringBuilder();
		for (Pair<String, String> pair : Arrays.asList(changeInfo)) {
			String left = pair.getLeft();
			String right = pair.getRight();
			if (StringUtils.isNotBlank(left)) {
				pairLeft.append(left).append(",");
			}
			if (StringUtils.isNotBlank(right)) {
				pairRight.append(right).append(",");
			}
		}
		String left;
		String right;
		if (pairLeft.length() > 0) {
			left = pairLeft.substring(0, pairLeft.length() -  1);
		} else {
			left = pairLeft.toString();
		}
		if (pairRight.length() > 0) {
			right = pairRight.substring(0, pairRight.length() - 1);
		} else {
			right = pairRight.toString();
		}
		return Pair.of(left, right);
	}

	@Transactional(rollbackFor = Exception.class)
	public Boolean enableComment(EnableCommentParam request) {
		LambdaQueryWrapper<CommentConfigurationDO> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(CommentConfigurationDO::getId, request.getId());
		List<CommentConfigurationDO> list = commentConfigurationBaseService.list(queryWrapper);

		PersonnelInfo loginUser = personnelThirdService.getLoginUserInfoInWeb();
		log.info("CommentConfigurationBizService#getLoginUserInfoInWeb:{}",JSON.toJSONString(loginUser));

		OperateRecordDO operateRecordDO = new OperateRecordDO();
		if (CollectionUtils.isNotEmpty(list)){
			CommentConfigurationDO configurationDO = list.get(0);
			operateRecordDO.setUpdateBefore(EnableFlagEnum.queryByType(configurationDO.getEnableFlag()).getDesc());
			configurationDO.setEnableFlag(request.getEnableFlag());
			boolean result = commentConfigurationBaseService.updateById(configurationDO);
			if (result){
				//修改更新操作记录
				operateRecordDO.setStoreNo("");
				operateRecordDO.setUpdateData(EnableFlagEnum.queryByType(request.getEnableFlag()).getDesc());
				if (!Objects.isNull(loginUser) && StringUtils.isNotBlank(loginUser.getRealName())){
					operateRecordDO.setUpdateFrom(loginUser.getRealName());
				}else {
					operateRecordDO.setUpdateFrom("");
				}
				if (!Objects.isNull(loginUser) && StringUtils.isNotBlank(loginUser.getDeptId())){
					operateRecordDO.setCreateDept(loginUser.getDeptId().split(",")[0]);
				}
				if (!Objects.isNull(loginUser) && ObjectUtils.isNotEmpty(loginUser.getId())){
					operateRecordDO.setCreateUser(String.valueOf(loginUser.getId()));
				}
				if (!Objects.isNull(loginUser) && ObjectUtils.isNotEmpty(loginUser.getFeishuEmpNo())){
					operateRecordDO.setUpdateFromCode(String.valueOf(loginUser.getFeishuEmpNo()));
				}
				operateRecordBaseService.addUpdateOptRecord(operateRecordDO);
			}
			return result;
		}
		return false;
	}

	public PaginationData<OperateRecordVo> queryOperateRecordPage(PaginationRequest<QueryOperateRecordParam> request) {
		Page<OperateRecordDO> page = new Page<>(request.getPageNum(), request.getPageSize());
		Page<OperateRecordDO> recordPage = operateRecordBaseService.queryRecordPage(request.getQueryParameter(), page);
		if (CollectionUtils.isEmpty(recordPage.getRecords())) {
			return ResponseUtil.emptyResponse(request, OperateRecordVo.class, recordPage.getTotal());
		}

		List<OperateRecordVo> arrayList = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(recordPage.getRecords())){
			OperateRecordVo result;
			for (OperateRecordDO record : recordPage.getRecords()) {
				result = new OperateRecordVo();
				result.setUpdateFromCode(record.getUpdateFromCode());
				result.setUpdateFrom(record.getUpdateFrom());
				result.setUpdateBefore(record.getUpdateBefore());
				result.setUpdateData(record.getUpdateData());
				result.setUpdateTime(record.getUpdateTime());
				arrayList.add(result);
			}
		}
		return ResponseUtil.commonResponse(request, arrayList, recordPage.getTotal());
	}
}
